/*
	memory_tables.h

	contains tables that assist in controlling the memory subsystem

	Author: Aidan Goddard 29/6/14
*/

#ifndef MEMORY_TABLES_H_INCLUDED
#define MEMORY_TABLES_H_INCLUDED

#include "types.h"
#include "lock.h"

struct bios_memory_entry
{
	uint64_t base;
	union
	{
		uint64_t length;
		uint64_t limit;
	};
	uint64_t type : 8;
	uint64_t pages : 56;
};

#ifdef __GCC_CROSS__
_Static_assert ((sizeof(struct bios_memory_entry) == 24), "bios_memory_entry structure is not the expected size");
#endif

struct virtual_allocation_control
{
	uint64_t physical_bitmap_PD_count;

	uint64_t available_virtual_memory;

	uint64_t available_2mb_PTs;
	uint64_t next_available_2mb_PT;
};

#ifdef __GCC_CROSS__
_Static_assert ((sizeof(struct virtual_allocation_control) == (32)), "virtual_allocation_control structure is not the expected size");
#endif

struct physical_allocation_control
{
	uint64_t sub_4gb_allocate_4kb_next;
	uint64_t sub_4gb_allocate_8kb_next;
	uint64_t sub_4gb_allocate_16kb_next;
	uint64_t sub_4gb_allocate_32kb_next;
	
	uint64_t post_4gb_allocate_4kb_next;
	uint64_t post_4gb_allocate_8kb_next;
	uint64_t post_4gb_allocate_16kb_next;
	uint64_t post_4gb_allocate_32kb_next;

	uint64_t sub_4gb_memory_available;
	uint64_t post_4gb_memory_available;

	uint64_t total_memory;
	uint64_t total_memory_available;
	uint64_t kernel_memory_allocated;
	uint64_t application_memory_allocated;

	uint64_t highest_address;

};

#ifdef __GCC_CROSS__
_Static_assert ((sizeof(struct physical_allocation_control) == (15 * 8)), "physical_allocation_control structure is not the expected size");
#endif

struct lazy_invalidation_entry
{
	uint64_t virtual_base;
	uint16_t page_count_4kb;
	uint16_t reserved1;
	uint32_t references_remaining;
};

#ifdef __GCC_CROSS__
_Static_assert ((sizeof(struct lazy_invalidation_entry) == 16), "lazy_invalidation_entry structure is not the expected size (16)");
#endif

struct lazy_invalidation_table
{
	struct lock_table lock;
	uint64_t max_entry_count;
	uint32_t next_entry_new;
	uint32_t next_entry_free;
	struct lazy_invalidation_entry *new_entries;
	struct lazy_invalidation_entry *free_entries;
};

#ifdef __GCC_CROSS__
_Static_assert ((sizeof(struct lazy_invalidation_table) == 64), "lazy_invalidation_table structure is not the expected size (64)");
#endif

struct lazy_invalidation_global_free_table
{
	struct lock_table lock;
	uint64_t max_entry_count;
	uint64_t next_entry;
	struct lazy_invalidation_entry *entries;
};

#ifdef __GCC_CROSS__
_Static_assert ((sizeof(struct lazy_invalidation_global_free_table) == 56), "lazy_invalidation_global_free_table structure is not the expected size (56)");
#endif

#endif